﻿
/** Pete's Objects package */
package pete.objects
{
	
	/**
	 * @version
	 * 0.1
	 *
	 * @description 
	 * Creates an array of options.
	 * The options can easily be cycled through with simple <code>myCycle.next ()</code> and <code>myCycle.previous ()</code> methods.
	 * At any time the current selection can be set and returned with <code>myCycle.current</code>.
	 * 
	 * @example
	 * <pre>
	 * var myCycle:Cycle = new Cycle ();
	 * </br>
	 * var object:Object = new Object ();
	 * object.name = "Object 1";
	 * var object2:Object = new Object ();
	 * object2.name = "Object 2";
	 * </br>
	 * myCycle.push (object);
	 * myCycle.push (object2);
	 * myCycle.next ();
	 * myCycle.next ();
	 * </br>
	 * trace (myCycle.current.name); // Output: Object 2
	 * </pre>
	 */
	public dynamic class Cycle extends Array
	{
		/**
		 * Integer representing the current selection of the array.
		 * <code>myCycle[currentIndex]</code> is the same as <code>myCycle.current</code>.
		 * When the objects of the cycle are deselected <code>currentIndex</code> will return as <code>-1</code>.
		 * 
		 * @see current
		 * @see oldIndex
		 */
		public var currentIndex:int;
		
		/**
		 * Integer representing the selection before <code>update ()</code>.
		 * 
		 * @see old
		 * @see currentIndex
		 */
		public var oldIndex:int;
		
		/**
		 * Sets and returns the current selection.
		 * 
		 * @see currentIndex
		 */
		public function get current ():Object
		{
			return this[currentIndex];
		}
		
		public function set current ($object:Object):void
		{
			oldIndex = currentIndex;
			currentIndex = indexOf ($object);
		}
		
		/**
		 * Returns the old selection.
		 * 
		 * @see oldIndex
		 * @see current
		 */
		public function get old ():Object
		{
			return this[oldIndex];
		}
		
		/**
		 * Tests if the Cycle is reset (<code>currentIndex = -1</code>).
		 */
		public function get isDefault ():Boolean
		{
			if (currentIndex == -1)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		
		/**
		 * Constructor
		 */
		public function Cycle ()
		{
			currentIndex = -1;
			oldIndex = -1;
		}
		
		
		/**
		 * Advances the current selection to the next object in the Cycle. Loops to begining.
		 * 
		 * @see previous ()
		 */
		public function next ():void
		{
			oldIndex = currentIndex;
			currentIndex++;
			
			if (currentIndex >= length)
			{
				currentIndex = 0;
			}
		}
		
		
		/**
		 * Reverses the current selection to the previous object in the Cycle. Loops to ending.
		 * 
		 * @see next ()
		 */
		public function previous ():void
		{
			oldIndex = currentIndex;
			currentIndex--;
			
			if (currentIndex < 0)
			{
				currentIndex = (length - 1);
			}
		}
		
		/**
		 * Resets the Cycle & deselects the objects.
		 */
		public function reset ():void
		{
			oldIndex = currentIndex;
			currentIndex = -1;
		}
		
		/**
		 * Returns an Array consisting of the properties of each Object in the Cycle.
		 * @param property String representing the property to search for.
		 */
		public function getByProperty (property:String):Array
		{
			var array:Array = new Array ();
			
			for each (var object in this)
			{
				array.push (object[property])
			}
			
			return array;
		}
		
	}
	
}